import { User, ChatMessage, ChatRoom, RoomMessage } from "../models/index.js";
import { success, successResponse, errorResponse } from "../utils/result.js";
import mongoose from "mongoose";

// 检查用户是否存在
const checkUserExists = async (uId) => {
  return await User.findById(uId);
};
// 验证uId是否有效
const checkuIdValid = (uId) => {
  if (!mongoose.Types.ObjectId.isValid(uId)) {
    throw new Error("输入的ID不是ObjectId格式");
  }
};

// 获取聊天会话列表
export const getChatList = async (req, res, next) => {
  const currentUserId = req.user.id;
  try {
    // 获取所有与当前用户相关的聊天记录
    const messages = await ChatMessage.find({
      $or: [{ senderId: currentUserId }, { recipientId: currentUserId }],
    })
      .sort({ timestamp: -1 })
      .populate("senderId", "username avatar")
      .populate("recipientId", "username avatar");

    // 按照聊天对象分组，只保留最新消息
    const chatMap = new Map();
    messages.forEach(async (message) => {
      // 聊天用户
      const otherId =
        message.senderId._id.toString() === currentUserId
          ? message.recipientId._id.toString()
          : message.senderId._id.toString();
      // 如果聊天用户不存在，则添加到chatMap
      if (!chatMap.has(otherId)) {
        const otherUser =
          message.senderId._id.toString() === currentUserId
            ? message.recipientId
            : message.senderId;
        chatMap.set(otherId, {
          id: otherId,
          type: "private",
          name: otherUser.username,
          avatar: otherUser.avatar,
          lastMessage: {
            id: message._id,
            content: message.content,
            timestamp: message.timestamp,
            read: message.read,
          },
        });
      }
    });
    const chatList = Array.from(chatMap.values());
    res.status(200).json(successResponse(chatList));
  } catch (error) {
    next(error);
  }
};
// 获取与特定用户的聊天历史
export const getChatHistory = async (req, res, next) => {
  const { uId } = req.params;
  const currentUserId = req.user.id;
  try {
    checkuIdValid(uId);
    const user = await checkUserExists(uId);
    if (!user) {
      return res.status(404).json(errorResponse("用户不存在"));
    }

    // 获取消息历史
    const messages = await ChatMessage.find({
      $or: [
        { senderId: currentUserId, recipientId: uId },
        { senderId: uId, recipientId: currentUserId },
      ],
    })
      .sort({ timestamp: 1 })
      .populate("senderId", "username avatar")
      .populate("recipientId", "username avatar")
      .lean();
    // 标记对方发送的未读消息为已读
    await ChatMessage.updateMany(
      {
        senderId: uId,
        recipientId: currentUserId,
        read: false,
      },
      { read: true }
    );

    res.status(200).json(successResponse(messages));
  } catch (error) {
    next(error);
  }
};

// 发送消息
export const sendMessage = async (req, res, next) => {
  const { recipientId, content } = req.body;
  const currentUserId = req.user.id;
  try {
    checkuIdValid(recipientId);
    const user = await checkUserExists(recipientId);
    if (!user) {
      return res.status(404).json(errorResponse("用户不存在"));
    }
    const message = new ChatMessage({
      senderId: currentUserId,
      recipientId: recipientId,
      content,
      timestamp: new Date(),
      read: false,
    });
    await message.save();
    res.status(200).json(success("发送成功"));
  } catch (error) {
    next(error);
  }
};

// 创建群聊
export const createRoom = async (req, res, next) => {
  const { name, description } = req.body;
  const currentUserId = req.user.id;
  try {
    const room = new ChatRoom({
      name,
      description,
      creator: currentUserId,
      members: [currentUserId],
    });
    await room.save();
    const roomDate = { id: room._id, name };
    res.status(200).json(successResponse(roomDate));
  } catch (error) {
    next(error);
  }
};

// 获取群聊列表
export const getRoomList = async (req, res, next) => {
  const currentUserId = req.user.id;
  try {
    const rooms = await ChatRoom.find({
      members: currentUserId,
    })
      .populate("creator", "username avatar")
      .populate("members", "username avatar");

    // 获取每个聊天室的最新消息和成员数量
    const roomList = await Promise.all(
      rooms.map(async (room) => {
        let lastMessage = await RoomMessage.findOne({
          roomId: room._id,
        }).sort({ timestamp: -1 });
        return {
          id: room._id,
          type: "room",
          name: room.name,
          avatar: room.creator.avatar,
          lastMessage: {
            id: lastMessage._id,
            content: lastMessage.content,
            timestamp: lastMessage.timestamp,
            read: lastMessage.read,
          },
        };
      })
    );

    res.status(200).json(successResponse(roomList));
  } catch (error) {
    next(error);
  }
};

// 获取群聊详情
export const getRoomDetail = async (req, res, next) => {
  const { rId } = req.params;
  try {
    const room = await ChatRoom.findById(rId)
      .populate("creator", "username avatar")
      .populate("members", "username avatar");
    if (!room) {
      return res.status(404).json(errorResponse("聊天室不存在"));
    }
    res.status(200).json(successResponse(room));
  } catch (error) {
    next(error);
  }
};

// 获取聊天室消息历史
export const getRoomHistory = async (req, res, next) => {
  const { rId } = req.params;
  try {
    const room = await ChatRoom.findById(rId);
    if (!room) {
      return res.status(404).json(errorResponse("聊天室不存在"));
    }
    const messages = await RoomMessage.find({ roomId: rId })
      .sort({ timestamp: 1 })
      .populate("senderId", "username avatar");
    // 标记消息已读
    await RoomMessage.updateMany({ roomId: rId }, { read: true });
    res.status(200).json(successResponse(messages));
  } catch (error) {
    next(error);
  }
};

// 删除聊天室
export const deleteRoom = async (req, res, next) => {
  const { rId } = req.params;
  const currentUserId = req.user.id;
  try {
    const room = await ChatRoom.findById(rId);
    if (!room) {
      return res.status(404).json(errorResponse("聊天室不存在"));
    }
    if (room.creator.toString() !== currentUserId) {
      return res.status(403).json(errorResponse("无权限"));
    }
    // 删除群聊
    await ChatRoom.findByIdAndDelete(rId);
    res.status(200).json(success("删除成功"));
  } catch (error) {
    next(error);
  }
};
